//
//  GraphViewController.m
//  ClinicalCollections
//
//  Created by janakiraman gopinath on 1/5/13.
//  Copyright (c) 2013 GOPI. All rights reserved.
//

#import "GraphViewController.h"
#import <QuartzCore/QuartzCore.h>
#import "CommonAPI.h"
#import "Cell.h"
#import "CCVSGraphData+Utilities.h"

#define i_index 0


@interface GraphViewController()
@property (nonatomic) NSArray *barChartArray;
@property (nonatomic) NSArray *pieChartArray;

@property (nonatomic)  NSMutableArray *overallStudy;


@end

@implementation GraphViewController

@synthesize dataForChart, dataForPlot;

@synthesize clinicalTrialGov = _clinicalTrialGov;

@synthesize barChartArray = _barChartArray;
@synthesize pieChartArray = _pieChartArray;

@synthesize overallStudy = _overallStudy;

-(NSArray *)sortDataArray:(NSArray *)dataArray
{
    NSArray *arrayToBeSorted = [dataArray copy];
    
    return [arrayToBeSorted sortedArrayUsingComparator:^NSComparisonResult(id first, id second) {
        NSDictionary *dict1 = (NSDictionary *)first;
        NSDictionary *dict2 = (NSDictionary *)second;
        NSArray *keys1 = [dict1 allKeys];
        NSArray *keys2 = [dict2 allKeys];
        NSString *string1 = keys1[0];
        NSString *string2 = keys2[0];
        
        return [string1 compare:string2 options:NSCaseInsensitiveSearch];
    }];
}

-(void)setBarChartArray:(NSArray *)barChartArray
{
    _barChartArray = [self sortDataArray:barChartArray] ;
    
}

-(void)setPieChartArray:(NSArray *)pieChartArray
{
    _pieChartArray = [self sortDataArray:pieChartArray] ;
    
}

#pragma mark -
#pragma mark Initialization and teardown


- (void) reload {
    if ( UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]) ) {
        self.scrollView.hidden = YES;
    }
    else {
        self.scrollView.hidden = NO;
    }
}
- (NSMutableArray *) overallStudy {
    
    if (!_overallStudy)
        _overallStudy = [[NSMutableArray alloc] initWithCapacity:MAX_CAPACITY];
    return _overallStudy;
}
-(void)viewDidLoad
{
    [super viewDidLoad];
    [self reload];
}


// This should be moved to COMMAPI
// The logic is very generic to ClinicalTrialGov
// For new data sources we need to populate the overallStudy array with ditionary from ClinicalTrialGov or the other source respectively based on the search type
// 
- (void) setClinicalTrialGov:(ClinicalTrialGov *)clinicalTrialGov
{
    //
    // Moved the original code to CCVSGraphData+Utilities so it can be shared more easily
    // will also make one place for changes and updates...
    self.overallStudy = [CCVSGraphData loadAllClinicalTrialGovGraphData:clinicalTrialGov];
    //
    //
    [self.collectionView reloadData];
}



#pragma mark -
#pragma mark Plot construction methods

-(NSArray *)removeTotalFromArray:(NSArray *) theDataArray
{
    NSMutableArray *dataArray = [theDataArray mutableCopy];
    
    int totalPosition = -1;
    for (int i=0; i< [dataArray count]; i++)
    {
        NSDictionary *element = [dataArray objectAtIndex:i];
        if ([[element allKeys][0] isEqualToString:@"Total"]) //Do not consider Total as a value to be plotted
            totalPosition = i;
    }
    if (totalPosition > -1)
        [dataArray removeObjectAtIndex:totalPosition];
    
    return [dataArray copy];
}

-(void)constructPieChart:(CPTGraphHostingView *) hostingView
{
    // Create pieChart from theme
    pieGraph = [[CPTXYGraph alloc] initWithFrame:CGRectZero];
    CPTTheme *theme = [CPTTheme themeNamed:kCPTDarkGradientTheme];
    [pieGraph applyTheme:theme];
    hostingView.hostedGraph             = pieGraph;
    pieGraph.plotAreaFrame.masksToBorder = NO;
    
    pieGraph.paddingLeft   = 5.0;
    pieGraph.paddingTop    = 5.0;
    pieGraph.paddingRight  = 5.0;
    pieGraph.paddingBottom = 5.0;
    
    pieGraph.axisSet = nil;
    
    
    // Prepare a radial overlay gradient for shading/gloss
    CPTGradient *overlayGradient = [[CPTGradient alloc] init];
    overlayGradient.gradientType = CPTGradientTypeRadial;
    overlayGradient              = [overlayGradient addColorStop:[[CPTColor blackColor] colorWithAlphaComponent:0.0] atPosition:0.0];
    overlayGradient              = [overlayGradient addColorStop:[[CPTColor blackColor] colorWithAlphaComponent:0.3] atPosition:0.9];
    overlayGradient              = [overlayGradient addColorStop:[[CPTColor blackColor] colorWithAlphaComponent:0.7] atPosition:1.0];
    // Add pie chart
    piePlot                 = [[CPTPieChart alloc] init];
    piePlot.dataSource = self;
    piePlot.delegate = self;
    piePlot.pieRadius       = 40;
    piePlot.identifier      = @"Therapy";
    piePlot.startAngle      = M_PI_4;
    piePlot.sliceDirection  = CPTPieDirectionCounterClockwise;
    piePlot.borderLineStyle = [CPTLineStyle lineStyle];
    piePlot.labelOffset     = 5.0;
    piePlot.overlayFill     = [CPTFill fillWithGradient:overlayGradient];
    
    [pieGraph addPlot:piePlot];
    
    NSArray *dataArray = [self removeTotalFromArray:self.pieChartArray];
    [graph.defaultPlotSpace scaleToFitPlots:dataArray];
    
}

-(void)constructBarChart:(CPTGraphHostingView *) hostingView;
{
    
    // Create barChart from theme
    barChart = [[CPTXYGraph alloc] initWithFrame:CGRectZero];
    
    CPTTheme *theme = [CPTTheme themeNamed:kCPTDarkGradientTheme];
    [barChart applyTheme:theme];
    hostingView.hostedGraph             = barChart;
    barChart.plotAreaFrame.masksToBorder = NO;
    barChart.paddingLeft   = 5.0; // Fix MC -- better fit
    barChart.paddingTop    = 5.0;
    barChart.paddingRight  = 5.0;
    barChart.paddingBottom = 5.0;
    
    // Add plot space for horizontal bar charts
    
    // Need to set ranges from data for the graph to look nice
    
    NSArray *dataArray = [self removeTotalFromArray:self.barChartArray];
    
    float  xMax, yMax;
    xMax = yMax = 0.0f;
    
    Class cls = [CommonAPI class];
    for (int i = 0; i < dataArray.count; i++)
        if ([((NSNumber *)[cls getValue:i graphDataArray:dataArray]) floatValue] > yMax)
            yMax = [((NSNumber *)[cls getValue:i graphDataArray:dataArray]) floatValue];
    
    CPTXYPlotSpace *plotSpace;
    
    plotSpace = (CPTXYPlotSpace *)barChart.defaultPlotSpace;
    
    plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) length:CPTDecimalFromFloat(yMax*1.5)]; //MC Fix -- make the yAxis 50% taller than the biggest yValue
    
    
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *)barChart.axisSet;
    CPTXYAxis *x          = axisSet.xAxis;
    x.axisLineStyle               = nil;
    x.majorTickLineStyle          = nil;
    x.minorTickLineStyle          = nil;
    x.majorIntervalLength         = CPTDecimalFromString(@"5");
    x.orthogonalCoordinateDecimal = CPTDecimalFromString(@"0");
    x.title                       = @"";
    x.titleLocation               = CPTDecimalFromFloat(7.5f);
    x.titleOffset                 = 10;
    x.labelRotation  = M_PI / 4;
    x.labelingPolicy = CPTAxisLabelingPolicyNone;
    
    NSMutableArray *treatmentLabels = [[NSMutableArray alloc] initWithCapacity:MAX_CAPACITY];
    
    for (int i = 0; i < dataArray.count; i++)
        [treatmentLabels addObject:[cls getGroup:i graphDataArray:dataArray]];
    
    NSArray *xAxisLabels         = [NSArray arrayWithArray:treatmentLabels];
    NSUInteger labelLocation     = 0;
    NSMutableArray *customLabels = [NSMutableArray arrayWithCapacity:[xAxisLabels count]];
    
    NSMutableArray *customTickLocationsArray = [[NSMutableArray alloc] initWithCapacity:MAX_CAPACITY];
    
    // Add number of categories - Treatment labels  in graph
    //
    
    for (int i = 0; i < xAxisLabels.count; i++)
        if(!i)
            [customTickLocationsArray addObject:[NSDecimalNumber numberWithInt:1]];
        else
            [customTickLocationsArray addObject:[NSDecimalNumber numberWithInt:i*5]];
    xMax = xAxisLabels.count * 5;
    plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) length:CPTDecimalFromFloat(xMax)];
    NSArray *customTickLocations = [NSArray arrayWithArray:customTickLocationsArray];
    
    for ( NSNumber *tickLocation in customTickLocations ) {
        CPTMutableTextStyle *textStyle = [[CPTMutableTextStyle alloc] init];
        textStyle.fontName = @"Arial";
        textStyle.fontSize = 5.0;
        textStyle.color = [CPTColor whiteColor];
        CPTAxisLabel *newLabel = [[CPTAxisLabel alloc] initWithText:[xAxisLabels objectAtIndex:labelLocation] textStyle:textStyle];
        labelLocation++;
        newLabel.tickLocation = [tickLocation decimalValue];
        newLabel.offset       = x.labelOffset + x.majorTickLength;
        newLabel.rotation     = M_PI / 8;
        [customLabels addObject:newLabel];
    }
    
    x.axisLabels = [NSSet setWithArray:customLabels];
    
    CPTXYAxis *y                  = axisSet.yAxis; // Fix MC -- for the thumbnail barchar, do not display yAxis ticks nor labels
    y.axisLineStyle               = nil;
    y.majorTickLineStyle          = nil;
    y.minorTickLineStyle          = nil;
    y.majorIntervalLength         = CPTDecimalFromFloat(0.0f);
    y.orthogonalCoordinateDecimal = CPTDecimalFromString(@"0");
    
    // First bar plot
    CPTBarPlot *barPlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor redColor] horizontalBars:NO];
    barPlot.baseValue  = CPTDecimalFromString(@"0");
    barPlot.dataSource = self;
    barPlot.delegate = self;
    barPlot.barOffset  = CPTDecimalFromFloat(0.750f); // Fix MC -- better start position for the first bar, so text is legible
    barPlot.identifier = @"Bar Plot 1";
    [barChart addPlot:barPlot toPlotSpace:plotSpace];
    [graph.defaultPlotSpace scaleToFitPlots:dataArray];
}
#pragma mark -
#pragma mark CPTBarPlot delegate method

-(void)barPlot:(CPTBarPlot *)plot barWasSelectedAtRecordIndex:(NSUInteger)index
{
    NSLog(@"barWasSelectedAtRecordIndex %d", index);
}

#pragma mark -
#pragma mark Plot Data Source Methods


-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
    int count = 0;
    
    if ([[CommonAPI class] checkGraphHostinView:plot hostingView:[self.overallStudy[[[plot graph] hostingView].tag] valueForKey:GRAPH_VIEW]]){
        NSArray *dataArray = [self removeTotalFromArray:[self.overallStudy[[[plot graph] hostingView].tag] valueForKey:DATA]];
        count = [dataArray count];
    }
    return count;
}

-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
    
    NSDecimalNumber *num = nil;
    NSArray *dataArray = nil;
    Class cls = [CommonAPI class];
    if ( [plot isKindOfClass:[CPTBarPlot class]] ) {
        switch ( fieldEnum ) {
            case CPTBarPlotFieldBarLocation:
                if (index == 0)
                    num = (NSDecimalNumber *) [NSDecimalNumber numberWithInt:1];
                else
                    num = (NSDecimalNumber *)[NSDecimalNumber numberWithUnsignedInteger:index*5];
                break;
                
            case CPTBarPlotFieldBarTip:
            {
                if ([[CommonAPI class] checkGraphHostinView:plot
                                                hostingView:[self.overallStudy[[[plot graph] hostingView].tag] valueForKey:GRAPH_VIEW]]) {
                    //Fix MC -- sorting dataArray in order to have consistance on the data displayed
                    dataArray = [self removeTotalFromArray:[self sortDataArray:[self.overallStudy[[[plot graph] hostingView].tag] valueForKey:DATA]]];
                    
                    num = (NSDecimalNumber *)[cls getValue:index graphDataArray:dataArray];
                }
            }
                break;
        }
    }
    else if ( [plot isKindOfClass:[CPTPieChart class]] ) {
        if ([[CommonAPI class] checkGraphHostinView:plot
                                        hostingView:[self.overallStudy[[[plot graph] hostingView].tag] valueForKey:GRAPH_VIEW]]) {
            //Fix MC -- sorting dataArray in order to have consistance on the data displayed
            dataArray = [self removeTotalFromArray:[self sortDataArray:[self.overallStudy[[[plot graph] hostingView].tag] valueForKey:DATA]]];
        }
        if (index >= [dataArray count])
            return nil;
        
        if ( fieldEnum == CPTPieChartFieldSliceWidth ) {
            num = (NSDecimalNumber *)[cls getValue:index graphDataArray:dataArray];
        }
        else {
            num = (NSDecimalNumber *)[NSDecimalNumber numberWithUnsignedInteger:index];
        }
    }
    
    return num;
}

-(CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)index
{
    
    static CPTMutableTextStyle *whiteText = nil;
    NSArray *dataArray = nil;
    Class cls = [CommonAPI class];
    if ( !whiteText ) {
        whiteText       = [[CPTMutableTextStyle alloc] init];
        whiteText.color = [CPTColor whiteColor];
    }
    
    CPTTextLayer *newLayer = nil;
    
    if ( [plot isKindOfClass:[CPTBarPlot class]] ) {
        if ([[CommonAPI class] checkGraphHostinView:plot
                                        hostingView:[self.overallStudy[[[plot graph] hostingView].tag] valueForKey:GRAPH_VIEW]]) {
            //Fix MC -- sorting dataArray in order to have consistance on the data displayed
            dataArray = [self removeTotalFromArray:[self sortDataArray:[self.overallStudy[[[plot graph] hostingView].tag] valueForKey:DATA]]];
        }
        
        unsigned long l = [[cls getValue:index graphDataArray:dataArray] longValue];
        
        newLayer = [[CPTTextLayer alloc] initWithText:[NSString stringWithFormat:@"%lu", (unsigned long)l] style:whiteText];
    }
    else if ( [plot isKindOfClass:[CPTPieChart class]] ) {
        
        unsigned long l = 0;
        if ([[CommonAPI class] checkGraphHostinView:plot
                                        hostingView:[self.overallStudy[[[plot graph] hostingView].tag] valueForKey:GRAPH_VIEW]]) {
            //Fix MC -- sorting dataArray in order to have consistance on the data displayed
            dataArray = [self removeTotalFromArray:[self sortDataArray:[self.overallStudy[[[plot graph] hostingView].tag] valueForKey:DATA]]];
            l = [[cls getValue:index graphDataArray:dataArray] longValue];
        }
        
        if (l) {
            //Fix MC -- get the label from the key in dataArray for the current index
            //NSString *label = [self.overallStudy[[[plot graph] hostingView].tag] valueForKey:DESCRIPTION];
            NSString *label = [[dataArray objectAtIndex:index] allKeys][0];
            CPTMutableTextStyle *textStyle = [[CPTMutableTextStyle alloc] init];
            textStyle.fontName = @"Arial";
            textStyle.fontSize = 8.0;
            textStyle.color = [CPTColor whiteColor];
            newLayer = [[CPTTextLayer alloc] initWithText:[NSString stringWithFormat:@"%@[%lu]", label, (unsigned long)l] style:textStyle];
        }
        else
            newLayer = (id)[NSNull null];
    }
    
    
    return newLayer;
}

#pragma mark -- Collection View Delete

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section;
{
    return self.overallStudy.count;
}

- (void) collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath
{
    [self performSegueWithIdentifier:@"showDetail" sender:self];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    SingleGraphViewController *sgvc =  [segue destinationViewController];
    
    int row = [[[self.collectionView indexPathsForSelectedItems] objectAtIndex:0] row];
    
    sgvc.chartType = [[self.overallStudy objectAtIndex:row] valueForKey:CHART_TYPE];
    
    sgvc.chartArray = [[self.overallStudy objectAtIndex:row] valueForKey:DATA];
    sgvc.chartTitle = [NSString stringWithFormat:@"%@", [self.overallStudy[row] valueForKey:DESCRIPTION]]; //Fix MC -- pass along the title of the graph
    
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath;
{
    // we're going to use a custom UICollectionViewCell, to hold the graphs
    //
    Cell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"CellId" forIndexPath:indexPath];
    
    
    // make the cell's title the actual NSIndexPath value
    cell.graphView.tag = indexPath.row;
    cell.label.text = [NSString stringWithFormat:@"%@", [self.overallStudy[indexPath.row] valueForKey:DESCRIPTION]];
    
    
    [[self.overallStudy objectAtIndex:indexPath.row] setObject:cell.graphView forKey:GRAPH_VIEW];
    if ([[[self.overallStudy objectAtIndex:indexPath.row] valueForKey:CHART_TYPE] isEqual:BAR_CHART]) {
        self.barChartArray = [[self.overallStudy objectAtIndex:indexPath.row] valueForKey:DATA];
        [self constructBarChart:cell.graphView];
    } else if ([[[self.overallStudy objectAtIndex:indexPath.row] valueForKey:CHART_TYPE] isEqual:PIE_CHART]) {
        self.pieChartArray = [[self.overallStudy objectAtIndex:indexPath.row] valueForKey:DATA];
        [self constructPieChart:cell.graphView];
    }
    return cell;
}


@end
